//#ifndef MINGW

// MSVC header
#include "stdafx.h"

//#endif


#include "keybdef.h"

#include <stdio.h>

bool initLayoutList(InputLayouts &vl)
{
    vl.clear();

    // 1. Read current registry settings of KLID
    HKEY rootKey = 0;
    long res = RegOpenCurrentUser(KEY_READ, &rootKey);
    if (res != ERROR_SUCCESS)
        return false;

    // preloaded KLIDs
    HKEY preloadKey = 0;
    res = RegOpenKeyEx(rootKey, _T("Keyboard Layout\\Preload"), 0, KEY_READ, &preloadKey);
    if (res != ERROR_SUCCESS)
    {
        RegCloseKey(rootKey);
        return false;
    }

    wchar_t name[20];
    int cnt = 1;
    unsigned char value[1024];
    DWORD type = REG_SZ;
    DWORD len = sizeof(value);

    do {
        // get value
        wsprintf(name, _T("%d"), cnt++);
        len = 1024;
        res = RegQueryValueEx(preloadKey, name, NULL, &type, value, &len);
        if (res != 0)
            break;

        InputLayoutInfo il;
        il.id = (wchar_t*)value;
        swscanf((wchar_t*)value, _T("%x"), &il.klid);

        //wprintf(_T("%s   %x \n"), il.id, il.klid);
        vl.push_back(il);
    } while (true);

    RegCloseKey(preloadKey);

    // substituted KLIDs
    HKEY substKey = 0;
    res = RegOpenKeyEx(rootKey, _T("Keyboard Layout\\Substitutes"), 0, KEY_READ, &substKey);
    if (res != ERROR_SUCCESS)
    {
        RegCloseKey(rootKey);
        return false;
    }

    cnt = vl.size();
    for (int i = 0; i < cnt; i++)
    {
        // get value
        len = 1024;
        res = RegQueryValueEx(preloadKey, vl[i].id.c_str(), NULL, &type, value, &len);
        if (res != 0)
            continue;

        // if found -> substitute
        vl[i].id = (wchar_t*)value;
        swscanf((wchar_t*)value, _T("%x"), &vl[i].klid);
    }

    RegCloseKey(substKey);
    RegCloseKey(rootKey);

    // 2. Obtain textual names
    res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts"), 0, KEY_READ, &rootKey);
    if (res != ERROR_SUCCESS)
    {
        return false;
    }

    HKEY nameKey = 0;
    for (int i = 0; i < cnt; i++)
    {
        // open key
        res = RegOpenKeyEx(rootKey, vl[i].id.c_str(), 0, KEY_READ, &nameKey);
        if (res != ERROR_SUCCESS)
            continue;

        // get value
        len = 1024;
        res = RegQueryValueEx(nameKey, _T("Layout Text"), NULL, &type, value, &len);
        RegCloseKey(nameKey);
        if (res != 0)
            continue;

        vl[i].name = (wchar_t*)value;

        //wprintf(_T("%s (%s)\n"), vl[i].name.c_str(), vl[i].id.c_str());
    }

    // 3. Get all installed HKLs
    HKL bf[100];
    int n = GetKeyboardLayoutList(100, bf);

    // 4. Put them into layout info list
    for (int i = 0; i < cnt; i++)
    {
        HKL kl = LoadKeyboardLayout(vl[i].id.c_str(), 0);

        vl[i].hkl = 0;

        for (int j = 0; j < n; j++)
        {
            if (kl == bf[j])
            {
                vl[i].hkl = kl;
                break;
            }
        }
    }

    return true;
}

